package com.example.tl;

import lombok.Data;
import lombok.experimental.Accessors;

import java.util.Random;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author zhangs
 * @version v1.0
 * @decription ThreadLocal
 * @date 2021/3/29 18:43
 **/
public class Two {
    // 支持静态方法和链式调用
    @Data(staticConstructor = "of")
    @Accessors(chain = true)
    static class User {
        private String name;
        private Integer age;
    }

    // LocalThread：用户持有类
    static class UserContextHolder {
        public static ThreadLocal<User> user =
                new ThreadLocal<>();
    }

    static class UserService01 {
        public void process(String name, Integer age) {
            // 创建用户类
            User user = User.of().setName(name).setAge(age);
            // 将用户类放入ThreadLocal
            UserContextHolder.user.set(user);
            Thread curr = Thread.currentThread();
            System.out.println(curr.getName() +
                    " - 创建的user：" + user);
            // 调用下一个UserService
            new UserService02().process();
        }
    }

    static class UserService02 {
        public void process() {
            User user = UserContextHolder.user.get();
            Thread curr = Thread.currentThread();
            System.out.println(curr.getName() +
                    " - 在UserService02中获取User对象:" + user);
            new UserService03().process();
        }
    }

    static class UserService03 {
        public void process() {
            User user = UserContextHolder.user.get();
            Thread curr = Thread.currentThread();
            System.out.println(curr.getName() +
                    " - 在UserService03中获取User对象:" + user);
            // 移除当前线程的User对象
            UserContextHolder.user.remove();
        }
    }

    public static void main(String[] args) {
        ExecutorService service = Executors
                .newFixedThreadPool(10);
        Random random = new Random();
        for (int i = 0; i < 1000; i++) {
            String name = UUID.randomUUID()
                    .toString().substring(2, 7);
            service.execute(() -> {
                new UserService01().process(name, random.nextInt(100));
            });
        }
        service.shutdown();
    }
}
